package de.hsowl.tod4a.client;

import java.io.File;
import java.io.IOException;

import de.hsowl.tod4a.global.exception.ObjectDatabaseException;
import de.hsowl.tod4a.global.model.ClientProperty;
import de.hsowl.tod4a.global.model.ServerProperty;

public abstract class EntityManagerFactory {

	/**
	 * Embedded EntityManager
	 */
	private static EntityManager em = null;
	/**
	 * Client-Server EntityManager
	 */
	private static EntityManager clientServer = null;

	/**
	 * Starts a Client Server Session
	 * 
	 * @Usage try{<br>
	 *        EntityManager em = EntityManagerFactory.clientServerSession();<br>
	 *        Customer customer = new Customer();<br>
	 *        em.store(customer);<br>
	 *        catch(Exception e){<br>
	 *        [handle exception]}<br>
	 * 
	 * @param host
	 *            - IP or URL of the server
	 * @param port
	 *            - Port of the Server
	 * @param username
	 *            - Username (Default: root)
	 * @param password
	 *            - Password (Default: root)
	 * @return EntityManger - DB Connection
	 * @throws ObjectDatabaseException
	 * @throws Exception
	 */
	public static EntityManager clientServerSession(String host, int port, String username, String password) throws IOException,
			ObjectDatabaseException {
		return clientServerSession(host, port, username, password, null);
	}

	/**
	 * Starts a Client Server Session
	 * 
	 * @Usage try{<br>
	 *        EntityManager em = EntityManagerFactory.clientServerSession();<br>
	 *        Customer customer = new Customer();<br>
	 *        em.store(customer);<br>
	 *        catch(Exception e){<br>
	 *        [handle exception]}<br>
	 * 
	 * @param host
	 * @param port
	 * @param username
	 * @param password
	 * @return
	 */
	public static EntityManager clientServerSession(String host, int port, String username, String password, ClientProperty props)
			throws IOException, ObjectDatabaseException {
		if (host == null) {
			throw new NullPointerException("host must =/= null");
		} else if (port <= 0) {
			throw new NullPointerException("port must > 0");
		} else if (username == null) {
			throw new NullPointerException("username must =/= null");
		} else if (password == null) {
			throw new NullPointerException("password must =/= null");
		}

		if (clientServer == null) {
			clientServer = new EntityManagerImpl(host, port, username, password, props);
		}
		return clientServer;
	}

	/**
	 * Starts an embedded Session. By Default a Server will also Start and can
	 * be used by other applications.
	 * 
	 * @param pathToDB
	 *            - Path to the DB directory e.g. /mnt/sdcard on Android (-> a
	 *            directory called tod4a will created in /mnt /sdcard)
	 * @return EntityManger - DB Connection
	 * @throws Exception
	 */
	public static EntityManager embeddedSession(File pathToDB) throws ObjectDatabaseException {
		if (pathToDB == null) {
			throw new NullPointerException("File must =/= null");
		}
		if (em == null) {
			em = new EntityManagerImpl(pathToDB);
		}
		return em;
	}

	/**
	 * {@link EntityManagerFactory#embeddedSession(File)}
	 * 
	 * @param pathToDB
	 * @return
	 * @throws Exception
	 */
	public static EntityManager embeddedSession(String pathToDB) throws ObjectDatabaseException {
		if (pathToDB != null && pathToDB.length() > 0) {
			return embeddedSession(new File(pathToDB));
		}
		throw new NullPointerException("path must =/= null");
	}

	/**
	 * Starts an embedded Session. By Default a Server will also start and can
	 * be used by other applications. To configure the server just edit the
	 * ServerProperty object by using new ServerProperty() or
	 * ServerProperty.getDefaultProperty()
	 * 
	 * @param pathToDB
	 *            - Path to the DB directory e.g. /mnt/sdcard on Android (-> a
	 *            directory called tod4a will created in /mnt /sdcard)
	 * @return EntityManger - DB Connection
	 * @throws Exception
	 */
	public static EntityManager embeddedSession(File pathToDB, ServerProperty property) throws ObjectDatabaseException {
		if (property == null) {
			throw new NullPointerException("ServerProperty must =/= null");
		} else if (pathToDB == null) {
			throw new NullPointerException("File must =/= null");
		}
		if (em == null) {
			em = new EntityManagerImpl(pathToDB, property);
		}
		return em;
	}

	/**
	 * Starts an embedded Session. In this Session no server will start
	 * 
	 * @param pathToDB
	 *            - Path to the DB directory e.g. /mnt/sdcard on Android (-> a
	 *            directory named tod4a will created in /mnt /sdcard)
	 * @return EntityManger - DB Connection
	 * @throws Exception
	 */
	public static EntityManager embeddedSessionWithoutServer(File pathToDB) throws ObjectDatabaseException {
		if (pathToDB == null) {
			throw new NullPointerException("File must =/= null");
		}
		if (em == null) {
			ServerProperty prop = ServerProperty.getDefaultProperty();
			prop.START_SERVER = false;
			em = new EntityManagerImpl(pathToDB, prop);
		}
		return em;
	}
}
